#include <stdio.h>
#include <string.h>
#include <map>
#include <vector>
#include <algorithm>

// Example struct
struct SAlumno
{
  int iAge;
  std::string szName;

  SAlumno(int age, const char* name)
  {
    iAge = age;
    szName = name;
  }
};


// Predicados que se usan para las funciones vectores
struct SCompareAgePredicate
{
  bool operator() (const SAlumno a, const SAlumno b) const
  {
    return a.iAge < b.iAge;
  }
};

// Predicados que se usan para las funciones vectores
struct SFindByName
{
  const char* pszName;
  SFindByName(const char* name) : pszName(name) {}

  bool operator() (const SAlumno a) const
  {
    return (strcmp(a.szName.c_str(), pszName) == 0);
  }
};

//---------------------------------------------------
//-- Main loop
//---------------------------------------------------
int main ()
{
  //------------------
  // Vector std
  //------------------
  typedef std::vector<SAlumno> tAlumnosVector;
  tAlumnosVector Alumnos;

  // Rellenar vector
  Alumnos.push_back(SAlumno(12, "Gabri"));
  Alumnos.push_back(SAlumno(32, "Tom"));
  Alumnos.push_back(SAlumno(52, "Calamar"));
  Alumnos.push_back(SAlumno(1, "Jose"));
  Alumnos.push_back(SAlumno(4, "Leo"));


  tAlumnosVector::const_iterator it;
  tAlumnosVector::const_iterator itEnd(Alumnos.end());

  // Acceder a la informacion del vector
  for (it = Alumnos.begin(); it != itEnd; ++it)
  {
    printf("Nombre del alumno %s y edad %d\n", (*it).szName.c_str(), (*it).iAge);
  }

  // Ordenacion y busqueda
  std::sort(Alumnos.begin(), Alumnos.end(), SCompareAgePredicate());
  tAlumnosVector::iterator ItFound = std::find_if(Alumnos.begin(), Alumnos.end(), SFindByName("Leo"));


  tAlumnosVector::iterator itDelete(Alumnos.begin());
  
  while (itDelete != Alumnos.end())
  {
    SAlumno a = *itDelete;
    if (a.szName == "Tom")
    {
      itDelete = Alumnos.erase(itDelete);
    }
    else
      ++itDelete;
  }

  printf("\n\n");



  //------------------
  // Map std
  //------------------
  typedef std::map<std::string, int> tAlumnosMap;
  tAlumnosMap AlumnosMap;

   // Rellenar map con insert y value_type
  AlumnosMap.insert(tAlumnosMap::value_type("Gabri", 12));
  AlumnosMap.insert(tAlumnosMap::value_type("Tom", 32));
  AlumnosMap.insert(tAlumnosMap::value_type("Calamar", 52));
  AlumnosMap.insert(tAlumnosMap::value_type("Jose", 1));
  AlumnosMap.insert(tAlumnosMap::value_type("Leo", 4));

  // o poseid usar
  AlumnosMap["Gabri"] = 12;
  AlumnosMap["Tom"] = 32;
  AlumnosMap["Calamar"] = 52;
  AlumnosMap["Jose"] = 1;
  AlumnosMap["Leo"] = 4;


  tAlumnosMap::const_iterator itMap;
  tAlumnosMap::const_iterator itEndMap(AlumnosMap.end());

  // Acceder a la informacion del map
  for (itMap = AlumnosMap.begin(); itMap != itEndMap; ++itMap)
  {
    printf("Nombre del alumno %s y edad %d\n", itMap->first.c_str(), itMap->second);
  }

  printf("\n\n");

  tAlumnosMap::const_iterator ItFoundMap = AlumnosMap.find("Calamar");
  if (ItFoundMap != itEndMap)
  {
    printf("Nombre %s encontrado con edad %d", ItFoundMap->first.c_str(), ItFoundMap->second);
  }

  // Vaciar vector y map
  Alumnos.clear();
  AlumnosMap.clear();
  
  return 0;
}